package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.constant.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.BlackListApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FriendApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.dubbo.api.mongo.VoiceApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Voice;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.VoiceVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author lamy
 * @version 1.0
 * @ClassName: VoiceService
 * @date 2021-12-26 10:26:11
 */
@Service
@Slf4j
public class VoiceService {
    @DubboReference
    private VoiceApi voiceApi;

    @DubboReference
    private BlackListApi blackListApi;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private FastFileStorageClient client;//文件上传客户端对象 /group1/M00/00/00/wKiIoGG_9YCACIIaAATPmhnHJ_s286.png

    @Autowired
    private FdfsWebServer fdfsWebServer; //获取 http://192.168.136.160:8888/路径

    @DubboReference
    private UserInfoApi userInfoApi;

    //桃花传音-发送语音
    public void sendVoice(MultipartFile soundFile) {

        try {
            Long userId = UserHolder.getUserId();
            //1.判断该用户语音是否发送语音超量
            String key = Constants.VOICE_SEND_KEY + userId;
            String number = stringRedisTemplate.opsForValue().get(key);
            if (number == null) {
                stringRedisTemplate.opsForValue().set(Constants.VOICE_SEND_KEY + userId, "0");
            }
            if (number != null && number.equals("3")) {
                throw new TanHuaException("超出今日发送次数");
            }
            //上传到文件服务器
            String suffix = soundFile.getOriginalFilename().substring(soundFile.getOriginalFilename().lastIndexOf(".") + 1); //.mp4 ==> mp4
            StorePath storePath = client.uploadFile(soundFile.getInputStream(), soundFile.getSize(), suffix, null);
            String soundUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
            //发送成功redis自增1
            stringRedisTemplate.opsForValue().increment(key);

            Voice voice = new Voice();
            voice.setVoiceUrl(soundUrl);
            voice.setUserId(userId);
            voiceApi.add(voice);

            log.debug("*****************语音发布成功了*****************");
        } catch (IOException e) {
            log.debug("*****************语音发布失败了*****************");
          /*  //发送失败，redis自减1
            RedisAtomicLong atomicLong = new RedisAtomicLong(key, stringRedisTemplate.getConnectionFactory());
            atomicLong.decrementAndGet();*/
            throw new TanHuaException(ErrorResult.error());
        }
    }

    //桃花传音-接收语音
    public VoiceVo getVoice() {
        Long userId = UserHolder.getUserId();
        //1.判断该用户语音是否接收语音超量
        String key = Constants.VOICE_LISTEN_KEY + userId;
        String number = stringRedisTemplate.opsForValue().get(key);
        if (number == null) {
            stringRedisTemplate.opsForValue().set(Constants.VOICE_LISTEN_KEY + userId, "3");
        }
        if (number != null && number.equals("0")) {
            throw new TanHuaException("超出今日接收次数");
        }

        //当前用户已听过的语音的ids
        String hearedKey = Constants.VOICE_HEARED_KEY+userId;
        List<String> hearedIds = stringRedisTemplate.opsForList().range(hearedKey,0,-1);
        if (hearedIds==null){
            hearedIds = new ArrayList<>();
        }
        List<ObjectId> objectIds = new ArrayList<>();
        for (String hearedId : hearedIds) {
            objectIds.add(new ObjectId(hearedId));
        }
        //返回当前用户的黑名单用户的ids
        List<Long> blackIds = blackListApi.findUserBlackIds(userId);
        //返回当前用户的好友ids
        List<Long> friendIds = friendApi.findUserFriendIds(userId);
        //返回当前用户喜欢表里的ids
        List<Long> likeIds = userLikeApi.findUserLikeIds(userId);
        //返回当前用户的同性的和年龄差大于5岁的Ids
        List<Long> userIds = userInfoApi.findSexAgeIds(userId);

        //去重合并这些Ids
        Set<Long> exclusionIds = new HashSet<>();
        //去掉自己的id
        exclusionIds.add(userId);
        exclusionIds.addAll(blackIds);
        exclusionIds.addAll(friendIds);
        exclusionIds.addAll(likeIds);
        exclusionIds.addAll(userIds);

        Voice voice = voiceApi.getVoice(objectIds,exclusionIds);

        if (voice==null){
            throw new TanHuaException("我们数据太少啦，语音听完了");
        }

        //接收一次redis自减1
        RedisAtomicLong atomicLong = new RedisAtomicLong(key, stringRedisTemplate.getConnectionFactory());
        long remainingTimes = atomicLong.getAndDecrement();
        //把这条语音的id存到redis
        stringRedisTemplate.opsForList().leftPushAll(hearedKey,voice.getId().toHexString());
        //得到该语音的用户信息
        Long voiceUserId = voice.getUserId();
        UserInfo voiceUserInfo = userInfoApi.getUserInfo(voiceUserId);

        //构造VO
        VoiceVo voiceVo = VoiceVo.init(voiceUserInfo, voice);
        voiceVo.setRemainingTimes((int) remainingTimes);
        return voiceVo;
    }
}
